//
//  CATranscationViewController.m
//  CoreAnimation
//
//  Created by 张国文 on 16/10/25.
//  Copyright © 2016年 hangzhouyijiyin. All rights reserved.
//

#import "CATranscationViewController.h"

@interface CATranscationViewController ()

@property (nonatomic, strong) UIView *backgroundView;

@property (nonatomic, strong) UIView *rectView;

@property (nonatomic, strong) CALayer *rectLayer;

@end

@implementation CATranscationViewController

/**
 *  事务是通过CATransaction类来做管理，这个类的设计有些奇怪，不像你从它的命名预期的那样去管理一个简单的事务，而是管理了一叠你不能访问的事务。CATransaction没有属性或者实例方法，并且也不能用+alloc和-init方法创建它。但是可以用+begin和+commit分别来入栈或者出栈。
 CATransaction适用于CALayer的类，不能对一个视图的关联图层做动画，因为视图的关联图层是将隐式动画禁用了的。
 
 Core Animation在每个run loop周期中自动开始一次新的事务（run loop是iOS负责收集用户输入，处理定时器或者网络事件并且重新绘制屏幕的东西），即使你不显式的用[CATransaction begin]开始一次事务,只写[CATransaction commit]，任何在一次run loop循环中属性的改变都会被集中起来，然后做一次0.25秒的动画。
 */

/**  
 ⚠️UIVIew的动画块和block回调动画块实际上内部都隐式的加入了CATransaction对layer层进行更改（任何看到的视图效果实际都是Layer层的绘制）。
 
 
  如果你用过UIView的动画方法做过一些动画效果，那么应该对这个模式不陌生。UIView有两个方法，+beginAnimations:context:和+commitAnimations，和CATransaction的+begin和+commit方法类似。实际上在+beginAnimations:context:和+commitAnimations之间所有视图或者图层属性的改变而做的动画都是由于设置了CATransaction的原因。
 
 在iOS4中，苹果对UIView添加了一种基于block的动画方法：+animateWithDuration:animations:。这样写对做一堆的属性动画在语法上会更加简单，但实质上它们都是在做同样的事情。
 
 CATransaction的+begin和+commit方法在+animateWithDuration:animations:内部自动调用，这样block中所有属性的改变都会被事务所包含。这样也可以避免开发者由于对+begin和+commit匹配的失误造成的风险。
*/

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    // 左边的方块是一个View，右边的方块是一个CALayer
    
    self.backgroundView = [[UIView alloc] initWithFrame:self.view.frame];
    self.backgroundView.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.5];
    [self.view addSubview:_backgroundView];
    
    self.rectView = [[UIView alloc] init];
    self.rectView.frame = CGRectMake(50, 100, 100, 100);
    self.rectView.backgroundColor = [UIColor redColor];
    [self.backgroundView addSubview:_rectView];
    
    self.rectLayer = [[CALayer alloc] init];
    self.rectLayer.frame = CGRectMake(200, 100, 100, 100);
    self.rectLayer.backgroundColor = [UIColor yellowColor].CGColor;
    [self.backgroundView.layer addSublayer:_rectLayer];
    
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
    button1.frame = CGRectMake(50, 300, 300, 30);
    [button1 setTitle:@"CATransaction" forState:UIControlStateNormal];
    [button1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button1 addTarget:self action:@selector(button1:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:button1];
    
    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
    button2.frame = CGRectMake(50, 350, 300, 30);
    [button2 setTitle:@"UIViewAnimation" forState:UIControlStateNormal];
    [button2 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button2 addTarget:self action:@selector(button2:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:button2];
    
    UIButton *button3 = [UIButton buttonWithType:UIButtonTypeCustom];
    button3.frame = CGRectMake(50, 400, 300, 30);
    [button3 setTitle:@"UIView的block动画" forState:UIControlStateNormal];
    [button3 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button3 addTarget:self action:@selector(button3:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:button3];
    
    UIButton *button4 = [UIButton buttonWithType:UIButtonTypeCustom];
    button4.frame = CGRectMake(50, 450, 300, 30);
    [button4 setTitle:@"CATransaction的完成块" forState:UIControlStateNormal];
    [button4 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button4 addTarget:self action:@selector(button4:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:button4];
}

- (void)button1:(UIButton *)button
{
    [CATransaction begin];
   // [CATransaction setDisableActions:YES]; // 关闭动画，颜色会在瞬间改变，默认为NO
    [CATransaction setAnimationDuration:3.0];
    CGFloat red = arc4random() % 256 / 255.0;
    CGFloat blue = arc4random() % 256 / 255.0;
    CGFloat green = arc4random() % 256 / 255.0;
    self.rectLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
    [CATransaction commit];
}

- (void)button2:(UIButton *)button
{
    [UIView beginAnimations:@"firstAnimation" context:nil];
    [UIView setAnimationDuration:3.0];
    CGFloat red = arc4random() % 256 / 255.0;
    CGFloat blue = arc4random() % 256 / 255.0;
    CGFloat green = arc4random() % 256 / 255.0;
    self.rectView.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1];
    [UIView commitAnimations];
}

- (void)button3:(UIButton *)button
{
    [UIView animateWithDuration:3.0 animations:^{
        CGFloat red = arc4random() % 256 / 255.0;
        CGFloat blue = arc4random() % 256 / 255.0;
        CGFloat green = arc4random() % 256 / 255.0;
        self.rectView.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1];
    }];
}

// 事务的完成块，我们在动画结束之后改变右边方块的旋转角度
- (void)button4:(UIButton *)button
{
    
    // 注意旋转动画要比颜色渐变快得多，这是因为完成块是在颜色渐变的事务提交并出栈之后才被执行，于是，用默认的事务做变换，默认的时间也就变成了0.25秒。
    [CATransaction begin];
    [CATransaction setAnimationDuration:3.0];
    [CATransaction  setCompletionBlock:^{
        self.rectLayer.affineTransform = CGAffineTransformRotate(self.rectLayer.affineTransform, M_PI_4);
    }];
    CGFloat red = arc4random() % 256 / 255.0;
    CGFloat blue = arc4random() % 256 / 255.0;
    CGFloat green = arc4random() % 256 / 255.0;
    self.rectLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1].CGColor;
    [CATransaction commit];
}



@end
